package com.solution.wx.core.util;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Formatter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.multipart.FilePart;
import org.apache.commons.httpclient.methods.multipart.MultipartRequestEntity;
import org.apache.commons.httpclient.methods.multipart.Part;
import org.apache.commons.httpclient.params.HttpMethodParams;
import org.apache.commons.httpclient.protocol.Protocol;
import org.apache.http.client.ClientProtocolException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.context.ContextLoader;
import org.springframework.web.context.WebApplicationContext;

import com.alibaba.fastjson.JSONObject;
import com.solution.admin.home.service.RedisService;
import com.solution.common.config.PublicConfigUtil;
import com.solution.common.utils.sms.MySSLProtocolSocketFactory;
import com.solution.common.utils.string.StringUtil;
import com.solution.wx.core.constants.WechatConstants;
import com.solution.wx.core.entity.SNSUserEntity;
import com.solution.wx.core.entity.sendmsg.ArticlesEntity;
import com.solution.wx.core.entity.sendmsg.BaseContentEntity;
import com.solution.wx.core.entity.sendmsg.BaseFilterEntity;
import com.solution.wx.core.entity.sendmsg.BaseMediaIdEntity;
import com.solution.wx.core.entity.sendmsg.SendCustomMsgImageEntity;
import com.solution.wx.core.entity.sendmsg.SendCustomMsgMpnewsEntity;
import com.solution.wx.core.entity.sendmsg.SendCustomMsgTextEntity;
import com.solution.wx.core.entity.sendmsg.SendMsgImageEntity;
import com.solution.wx.core.entity.sendmsg.SendMsgMpnewsByTagEntity;
import com.solution.wx.core.entity.sendmsg.SendMsgMpnewsEntity;
import com.solution.wx.core.entity.sendmsg.SendMsgParamEntity;
import com.solution.wx.core.entity.sendmsg.SendMsgTextEntity;

/**
 * 微信工具类
 * @author: solin
 * @date: 2017年11月12日 上午09:46:53
 */
public class WechatUtil {
	private static Logger logger = LoggerFactory.getLogger(WechatUtil.class);
	// 获取Spring容器
	private static WebApplicationContext webApplicationContext = ContextLoader.getCurrentWebApplicationContext();
	
	//自定义 token
	public static String TOKEN = "njjx";
	// snsapi_base(不需要弹出授权页面,只能获取openid)  
	public static String SCOPE_SNSAPIBASE = "snsapi_base"; 
	// 弹出授权页面(获取用户基本信息) 
	public static String SCOPE_SNSPAIUSERINFO = "snsapi_userinfo";
	
	//appID
	public static String APPID = PublicConfigUtil.readConfig("wxpay.appId");
	//appsecret
	public static String APPSECRET = PublicConfigUtil.readConfig("wxpay.appSecret");
	//请求jspi_ticket接口地址(使用时将ACCESS_TOKEN替换)
	public static String JSPI_TICKET_URL = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi";
	//请求access_token接口地址
	public static String ACCESS_TOKEN_URL = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET";
	//oauth2请求access_token接口地址
	public static String AUTH_ACCESS_TOKEN_URL = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=APPSECRET&code=CODE&grant_type=authorization_code";
	//拼接微信认证地址
	public static String AUTHORIZE_URL = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=ENCODE_REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect";
	// 图文内的图片地址获取接口地址
	private static String UPLOAD_IMAGE_URL = "https://api.weixin.qq.com/cgi-bin/media/uploadimg?access_token=ACCESS_TOKEN";
	//上传永久素材接口
	public static String UPLOAD_MATERIAL_URL = "https://api.weixin.qq.com/cgi-bin/material/add_material?access_token=ACCESS_TOKEN&type=TYPE";
	//多媒体文件临时上传接口（保存三天）(图文封面图片获取接口地址)
	public static String UPLOAD_MEDIA_URL = "https://api.weixin.qq.com/cgi-bin/media/upload?access_token=ACCESS_TOKEN&type=TYPE";
	//多媒体文件下载接口
	public static String DOWNLOAD_MEDIA_URL = "https://api.weixin.qq.com/cgi-bin/media/get?access_token=ACCESS_TOKEN&media_id=MEDIA_ID";
	//上传图文消息内的图片获取URL
	public static String GET_UPLOADIMG_URL = "https://api.weixin.qq.com/cgi-bin/media/uploadimg?access_token=ACCESS_TOKEN";
	//上传图文消息素材
	public static String UPLOAD_NEWS_URL = "https://api.weixin.qq.com/cgi-bin/media/uploadnews?access_token=ACCESS_TOKEN";
	//群发接口地址(根据OpenID列表群发【订阅号不可用，服务号认证后可用】)
	public static String SEND_NEWS_URL = "https://api.weixin.qq.com/cgi-bin/message/mass/send?access_token=ACCESS_TOKEN";
	//群发接口地址(根据标签进行群发【订阅号与服务号认证后均可用】)
	public static String SEND_DALL_URL ="https://api.weixin.qq.com/cgi-bin/message/mass/sendall?access_token=ACCESS_TOKEN";
	//群发预览接口地址
	private static String SEND_PREVIEW_URL = "https://api.weixin.qq.com/cgi-bin/message/mass/preview?access_token=ACCESS_TOKEN";
	
	/**
	 * 获取基础支持的access_token
	 * @return
	 * @author: solin
	 * @date: 2017年11月22日 下午7:14:22
	 */
	public static String getAccessToken(){
		String url = ACCESS_TOKEN_URL.replace("APPID", APPID).replace("APPSECRET", APPSECRET);
		String accessToken = null;
		try {
			RedisService redisService = webApplicationContext.getBean("redisServiceImpl", RedisService.class);
			if (null ==  redisService.get(WechatConstants.ACCESS_TOKEN_CACHE_KEY)) {
				String respStr = doPost(url, "");
				if (StringUtil.isNotEmpty(respStr)){
					JSONObject tokenResult = JSONObject.parseObject(respStr);
					accessToken = tokenResult.getString("access_token");
					
					redisService.saveSys(WechatConstants.ACCESS_TOKEN_CACHE_KEY, accessToken);
					// 7200 为两个小时，为了保险设置7000
					redisService.expire(WechatConstants.ACCESS_TOKEN_CACHE_KEY, 7000);
				}
			} else {
				accessToken = redisService.get(WechatConstants.ACCESS_TOKEN_CACHE_KEY);
			} 
		} catch (HttpException e) {
			logger.error("获取基础支持的access_token失败:{}", e);
		} catch (IOException e) {
			logger.error("获取基础支持的access_token失败:{}", e);
		}
		return accessToken;
	}
	
	/**
     * 通过code换取网页授权access_token（与基础支持中的access_token不同） 
     * @param code
     * @return
     */
	public static JSONObject getAccessTokenForCode(String code) {
		JSONObject tokenResult =  new JSONObject();
		String url = AUTH_ACCESS_TOKEN_URL.replace("APPID", APPID).replace("APPSECRET", APPSECRET).replace("CODE", code);
		String respStr = "";
		try {
			respStr = doPost(url, "");
			tokenResult = JSONObject.parseObject(respStr);
			//若是openId不为空则获取对应的用户信息
			//String openId = tokenResult.getString("openid");
			//String accessToken = tokenResult.getString("access_token");
		} catch (HttpException e) {
			logger.error("通过code换取网页授权access_token失败:{}", e);
		} catch (IOException e) {
			logger.error("通过code换取网页授权access_token失败:{}", e);
		}
		return tokenResult;
	}
	
	/**
	 * 从cookie中获取openId
	 * @param request
	 * @return
	 * @author: solin
	 * @date: 2017年11月21日 下午3:56:17
	 */
	public static String getOpenIdFromCookie(HttpServletRequest request){
		String openId = "";
		// 获取cookie信息
		Cookie[] cookie = request.getCookies();
		// 先从cookie里面获取用户的信息，如果获取到用户信息则放行；如果获取不到用户信息则要跳转到授权页面。
		if (null != cookie) {
			for (int i = 0; i < cookie.length; i++) {
				if (StringUtil.isNotNull(cookie[i].getName())
						&& "openId".equals(cookie[i].getName())) {
					openId = cookie[i].getValue();
				}
			}
		}
		return openId;
	}
	
	/**
	 * 获取调用微信JS接口的临时票据
	 * @param accessToken
	 * @return
	 * @author: solin
	 * @date: 2017年11月22日 下午5:00:52
	 */
	public static String getJspiTicket() {
		String ticket = null;
		try {
			RedisService redisService = webApplicationContext.getBean("redisServiceImpl", RedisService.class);
			
			String accessToken = redisService.get(WechatConstants.ACCESS_TOKEN_CACHE_KEY);
			if (StringUtil.isEmpty(accessToken)) {
				getAccessToken();
				accessToken = redisService.get(WechatConstants.ACCESS_TOKEN_CACHE_KEY);
			}
			JSONObject jsonObject = new JSONObject();
			JSONObject postjson = new JSONObject();
			
			String url = JSPI_TICKET_URL.replace("ACCESS_TOKEN", accessToken);
			if (null == redisService.get(WechatConstants.JSAPI_TICKET_CACHE_KEY)) {
				System.out.println("请求ticket的url"+url);
				jsonObject = JSONObject.parseObject(doPost(url, postjson.toString()));
				ticket = jsonObject.getString("ticket");
				System.out.println("获取ticket:" + ticket);
				if (null != ticket) {
					redisService.saveSys(WechatConstants.JSAPI_TICKET_CACHE_KEY, ticket);
					// 7200 为两个小时，为了保险设置7000
					redisService.expire(WechatConstants.JSAPI_TICKET_CACHE_KEY, 7000);
				}
			} else {
				ticket = redisService.get(WechatConstants.JSAPI_TICKET_CACHE_KEY);
				System.out.println("从redis中获取ticket:" + ticket);
			}
		} catch (Exception e) {
			logger.error("获取调用微信JS接口的临时票据失败:{}", e);
		}
		return ticket;
	};
	
	/**
	 * 签名
	 * @param jsapi_ticket
	 * @param url “公众号设置---功能设置----JS接口安全域名”中绑定的三个域名之一
	 * @return
	 * @author: solin
	 * @date: 2017年11月22日 下午5:03:29
	 */
	public static Map<String, String> sign(String jsapi_ticket, String url) {
		Map<String, String> ret = new HashMap<String, String>();
		String nonce_str = create_nonce_str();
		String timestamp = create_timestamp();
		String string1;
		String signature = "";

		// 注意这里参数名必须全部小写，且必须有序
		string1 = "jsapi_ticket=" + jsapi_ticket + "&noncestr=" + nonce_str
				+ "&timestamp=" + timestamp + "&url=" + url;
		System.out.println(string1);

		try {
			MessageDigest crypt = MessageDigest.getInstance("SHA-1");
			crypt.reset();
			crypt.update(string1.getBytes("UTF-8"));
			signature = byteToHex(crypt.digest());
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}

		ret.put("url", url);
		ret.put("jsapi_ticket", jsapi_ticket);
		ret.put("nonceStr", nonce_str);
		ret.put("timestamp", timestamp);
		ret.put("signature", signature);

		return ret;
	}

	private static String byteToHex(final byte[] hash) {
		Formatter formatter = new Formatter();
		for (byte b : hash) {
			formatter.format("%02x", b);
		}
		String result = formatter.toString();
		formatter.close();
		return result;
	}

	private static String create_nonce_str() {
		return UUID.randomUUID().toString();
	}

	private static String create_timestamp() {
		return Long.toString(System.currentTimeMillis() / 1000);
	}
	
	/**
     * 通过网页授权获取用户信息
     * 
     * @param accessToken 网页授权接口调用凭证
     * @param openId 用户标识
     * @return SNSUserInfo
	 * @throws IOException 
	 * @throws HttpException 
     */
	@SuppressWarnings({ "deprecation", "unchecked" })
	public static SNSUserEntity getSNSUserInfo(String accessToken, String openId)
			throws HttpException, IOException {
		SNSUserEntity snsUserInfo = null;
		// 拼接请求地址
		String requestUrl = "https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID";
		requestUrl = requestUrl.replace("ACCESS_TOKEN", accessToken).replace("OPENID", openId);
		// 通过网页授权获取用户信息
		String respStr = doPost(requestUrl, "");
		JSONObject jsonObject = JSONObject.parseObject(respStr);

		if (null != jsonObject) {
			try {
				snsUserInfo = new SNSUserEntity();
				// 用户的标识
				snsUserInfo.setOpenId(jsonObject.getString("openid"));
				// 昵称
				snsUserInfo.setNickname(jsonObject.getString("nickname"));
				// 性别（1是男性，2是女性，0是未知）
				snsUserInfo.setSex(jsonObject.getIntValue("sex"));
				// 用户所在国家
				snsUserInfo.setCountry(jsonObject.getString("country"));
				// 用户所在省份
				snsUserInfo.setProvince(jsonObject.getString("province"));
				// 用户所在城市
				snsUserInfo.setCity(jsonObject.getString("city"));
				// 用户头像
				snsUserInfo.setHeadImgUrl(jsonObject.getString("headimgurl"));
				// 用户特权信息
				snsUserInfo.setPrivilegeList((List)jsonObject.getJSONArray("privilege"));
			} catch (Exception e) {
				snsUserInfo = null;
				int errorCode = jsonObject.getIntValue("errcode");
				String errorMsg = jsonObject.getString("errmsg");
				// logger.error("获取用户信息失败 errcode:{} errmsg:{}", errorCode,
				// errorMsg);
			}
		}
		return snsUserInfo;
	}
	
	public static String doPost(String url, String responeJsonStr) throws IOException, HttpException {
		String responseContent = "";
		Protocol myhttps = new Protocol("https", new MySSLProtocolSocketFactory(), 443);
		Protocol.registerProtocol("https", myhttps);

		HttpClient client = new HttpClient();
		PostMethod post = new PostMethod(url);
		
		post.setRequestHeader(
				"User-Agent",
				"Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:30.0) Gecko/20100101 Firefox/30.0");
		post.setRequestHeader("Host", "file.api.weixin.qq.com");
		post.setRequestHeader("Connection", "Keep-Alive");
		post.setRequestHeader("Cache-Control", "no-cache");
		post.getParams().setParameter(HttpMethodParams.HTTP_CONTENT_CHARSET, "UTF-8");
		try {
			post.setRequestBody(responeJsonStr);
			int status = client.executeMethod(post);
			if (status == HttpStatus.SC_OK) {
				responseContent = post.getResponseBodyAsString();
			}
		} catch (Exception e) {
			e.printStackTrace();
		} 
		return responseContent;
	}
	
	/**
	 * 微信服务器素材上传
	 * 
	 * @param file
	 *            表单名称media
	 * @param token
	 *            access_token
	 */
	public static JSONObject uploadMaterial(File file, String token, String type) {
		if (file == null || token == null || type == null) {
			return null;
		}

		if (!file.exists()) {
			logger.info("上传文件不存在,请检查!");
			return null;
		}

		String url = UPLOAD_MATERIAL_URL.replace("ACCESS_TOKEN", token).replace("TYPE", type);
		JSONObject jsonObject = null;
		PostMethod post = new PostMethod(url);
		post.setRequestHeader("Connection", "Keep-Alive");
		post.setRequestHeader("Cache-Control", "no-cache");
		HttpClient httpClient = new HttpClient();
		// 信任任何类型的证书
		Protocol myhttps = new Protocol("https",
				new MySSLProtocolSocketFactory(), 443);
		Protocol.registerProtocol("https", myhttps);

		try {
			Part[] parts = new Part[] { new FilePart("media", file) };
			MultipartRequestEntity entity = new MultipartRequestEntity(parts,
					post.getParams());
			post.setRequestEntity(entity);
			int status = httpClient.executeMethod(post);
			if (status == HttpStatus.SC_OK) {
				String text = post.getResponseBodyAsString();
				jsonObject = JSONObject.parseObject(text);
			} else {
				logger.info("upload Media failure status is:" + status);
			}
		} catch (FileNotFoundException e) {
			logger.error("{}", e);
		} catch (HttpException e) {
			logger.error("{}", e);
		} catch (IOException e) {
			logger.error("{}", e);
		}
		return jsonObject;
	}
	
	/**
	 * 微信服务器素材上传
	 * 
	 * @param file
	 *            表单名称media
	 * @param token
	 *            access_token
	 * @param type
	 *            type只支持四种类型素材(video/image/voice/thumb)
	 */
	public static JSONObject uploadMedia(File file, String token, String type) {
		if (file == null || token == null || type == null) {
			return null;
		}

		if (!file.exists()) {
			logger.info("上传文件不存在,请检查!");
			return null;
		}

		String url = UPLOAD_MEDIA_URL.replace("ACCESS_TOKEN", token).replace("TYPE", type);
		JSONObject jsonObject = null;
		PostMethod post = new PostMethod(url);
		post.setRequestHeader("Connection", "Keep-Alive");
		post.setRequestHeader("Cache-Control", "no-cache");
		HttpClient httpClient = new HttpClient();
		// 信任任何类型的证书
		Protocol myhttps = new Protocol("https",
				new MySSLProtocolSocketFactory(), 443);
		Protocol.registerProtocol("https", myhttps);

		try {
			Part[] parts = new Part[] { new FilePart("media", file) };
			MultipartRequestEntity entity = new MultipartRequestEntity(parts,
					post.getParams());
			post.setRequestEntity(entity);
			int status = httpClient.executeMethod(post);
			if (status == HttpStatus.SC_OK) {
				String text = post.getResponseBodyAsString();
				jsonObject = JSONObject.parseObject(text);
			} else {
				logger.info("upload Media failure status is:" + status);
			}
		} catch (FileNotFoundException e) {
			logger.error("{}", e);
		} catch (HttpException e) {
			logger.error("{}", e);
		} catch (IOException e) {
			logger.error("{}", e);
		}
		return jsonObject;
	}
	
	/**
	 * 多媒体下载接口
	 * 
	 * @comment 不支持视频文件的下载
	 * @param fileName
	 *            素材存储文件路径
	 * @param token
	 *            认证token
	 * @param mediaId
	 *            素材ID（对应上传后获取到的ID）
	 * @return 素材文件
	 */
	public static File downloadMedia(String fileName, String token,
			String mediaId) {
		String url = DOWNLOAD_MEDIA_URL.replace("ACCESS_TOKEN", WechatUtil.getAccessToken()).replace("MEDIA_ID", mediaId);
		return httpRequestToFile(fileName, url, "GET", null);
	}
	
	/**
	 * 以http方式发送请求,并将请求响应内容输出到文件
	 * 
	 * @param path
	 *            请求路径
	 * @param method
	 *            请求方法
	 * @param body
	 *            请求数据
	 * @return 返回响应的存储到文件
	 */
	@SuppressWarnings("restriction")
	public static File httpRequestToFile(String fileName, String path,
			String method, String body) {
		if (fileName == null || path == null || method == null) {
			return null;
		}

		File file = null;
		HttpURLConnection conn = null;
		InputStream inputStream = null;
		FileOutputStream fileOut = null;
		try {
			URL url = new URL(path);
			conn = (HttpURLConnection) url.openConnection();
			conn.setDoOutput(true);
			conn.setDoInput(true);
			conn.setUseCaches(false);
			conn.setRequestMethod(method);
			if (null != body) {
				OutputStream outputStream = conn.getOutputStream();
				outputStream.write(body.getBytes("UTF-8"));
				outputStream.close();
			}

			inputStream = conn.getInputStream();
			if (inputStream != null) {
				file = new File(fileName);
			} else {
				return file;
			}

			// 写入到文件
			fileOut = new FileOutputStream(file);
			if (fileOut != null) {
				int c = inputStream.read();
				while (c != -1) {
					fileOut.write(c);
					c = inputStream.read();
				}
			}
		} catch (Exception e) {
			logger.error("{}", e);
		} finally {
			if (conn != null) {
				conn.disconnect();
			}

			/*
			 * 必须关闭文件流 否则JDK运行时，文件被占用其他进程无法访问
			 */
			try {
				if(inputStream != null){
					inputStream.close();
				}
				if(fileOut != null){
					fileOut.close();
				}
			} catch (IOException e) {
				logger.error("{}", e);
			}
		}
		return file;
	}
	
	/**
	 * 替换图文中的图片SRC为微信的图片URL
	 * @param ynr 图文内容
	 * @param index 从第几个字符开始替换
	 * @param fileDirPath 图片所在文件夹路径
	 * @return
	 * @author: solin
	 * @date: 2018年1月25日 上午9:54:16
	 */
	public static String replaceImgUrlOfMpNews(String ynr, int index, String fileDirPath){
		int srcStart = ynr.indexOf("src=\"", index); //获取src出现的位置
		if (srcStart == -1) {
			return ynr;
		}
		int srcEnd = ynr.indexOf("\"", srcStart+7);
		srcStart = srcStart + 5;
		String imgSrc = ynr.substring(srcStart, srcEnd); //获取图片路径(阿里云图片地址)
		String fileName = fileDirPath + "\\" + imgSrc.substring(imgSrc.lastIndexOf("/")+1); 
		File file = httpRequestToFile(fileName, imgSrc, "GET", null);
		//执行上传图片方法
		String url = GET_UPLOADIMG_URL.replace("ACCESS_TOKEN", getAccessToken());
		String scptjg = postImageFile(url, file);
		JSONObject scptjgJson = JSONObject.parseObject(scptjg);
		String newPath = scptjgJson.getString("url");
		// 替换字符串中该图片路径
		if(StringUtil.isNotEmpty(newPath)){
			ynr = ynr.replace(imgSrc, newPath);
		}
		// 查看字符串下方是否还有img标签
		int sfhyImg = ynr.indexOf("<img", srcEnd);
		if (sfhyImg == -1) {
			return ynr;
		} else {
			return replaceImgUrlOfMpNews(ynr, srcEnd, fileDirPath);
		}

	}
	
	/**
	 * 上传图片素材/上传图文消息内的图片获取URL 
	 * @param url 微信获取图片URL的连接
	 * @param filePath 图片绝对路径
	 * @return
	 * @author: solin
	 * @date: 2018年1月25日 上午10:35:10
	 */
	public static String postImageFile(String url, File file) {
	    //File file = new File(filePath);
	    if (!file.exists())
	        return null;
	    String result = "";
	    try {
	        URL url1 = new URL(url);
	        HttpURLConnection conn = (HttpURLConnection) url1.openConnection();
	        conn.setConnectTimeout(5000);
	        conn.setReadTimeout(30000);
	        conn.setDoOutput(true);
	        conn.setDoInput(true);
	        conn.setUseCaches(false);
	        conn.setRequestMethod("POST");
	        conn.setRequestProperty("Connection", "Keep-Alive");
	        conn.setRequestProperty("Cache-Control", "no-cache");
	        String boundary = "-----------------------------" + System.currentTimeMillis();
	        conn.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary);

	        OutputStream output = conn.getOutputStream();
	        output.write(("--" + boundary + "\r\n").getBytes());
	        output.write(
	                String.format("Content-Disposition: form-data; name=\"media\"; filename=\"%s\"\r\n", file.getName())
	                        .getBytes());
	        output.write("Content-Type: image/jpeg \r\n\r\n".getBytes());
	        byte[] data = new byte[1024];
	        int len = 0;
	        FileInputStream input = new FileInputStream(file);
	        while ((len = input.read(data)) > -1) {
	            output.write(data, 0, len);
	        }
	        output.write(("\r\n--" + boundary + "\r\n\r\n").getBytes());
	        output.flush();
	        output.close();
	        input.close();
	        InputStream resp = conn.getInputStream();
	        StringBuffer sb = new StringBuffer();
	        while ((len = resp.read(data)) > -1)
	            sb.append(new String(data, 0, len, "utf-8"));
	        resp.close();
	        result = sb.toString();
	    } catch (ClientProtocolException e) {
	        logger.error("postFile，不支持http协议", e);
	    } catch (IOException e) {
	        logger.error("postFile数据传输失败", e);
	    }
	    return result;
	}
	
	/**
	 * 上传图文消息素材，最多上传8个图文 
	 * @param articles
	 * @param token
	 * @return
	 * @author: solin
	 * @date: 2017年12月5日 下午4:36:00
	 */
	public static JSONObject uploadNews(ArticlesEntity articles, String token) {
		JSONObject jsonObject = null;
		String url = UPLOAD_NEWS_URL.replace("ACCESS_TOKEN", token);
		String responeJsonStr = JSONObject.toJSONString(articles);
		String text;
		try {
			text = doPost(url, responeJsonStr);
			jsonObject = JSONObject.parseObject(text);
		} catch (Exception e) {
			logger.error("{}", e);
		}
		
		return jsonObject;
	}
	
	/**
	 * 发送消息
	 * @param param
	 * @param token
	 * @return
	 * @author: solin
	 * @date: 2017年12月6日 下午7:53:18
	 */
	public static JSONObject sendNews(SendMsgParamEntity param, String token) {
		JSONObject jsonObject = null;
		String url = "";
		if ("openId".equals(param.getSendMode())) {
			url = SEND_NEWS_URL.replace("ACCESS_TOKEN", token);
		} else if ("tag".equals(param.getSendMode())) {
			url = SEND_DALL_URL.replace("ACCESS_TOKEN", token);
		} else if (param.getSendMode().contains("preview")) {
			url = SEND_PREVIEW_URL.replace("ACCESS_TOKEN", token);
		} else if ("delete".equals(param.getSendMode())) {
			
		}
		
		String responeJsonStr = getSendMsgJsonStr(param);
		String text;
		try {
			text = doPost(url, responeJsonStr);
			jsonObject = JSONObject.parseObject(text);
		} catch (Exception e) {
			logger.error("{}", e);
		}
		
		return jsonObject;
	}
	
	/**
	 * 组装消息发送JSON数据
	 * @param param
	 * @return
	 * @author: solin
	 * @date: 2017年12月5日 下午6:53:58
	 */
	public static String getSendMsgJsonStr(SendMsgParamEntity param) {
		String sendMsgJsonStr = "";
		
		BaseFilterEntity filter = new BaseFilterEntity();
		filter.setIs_to_all(param.getIs_to_all());
		filter.setTag_id(param.getTag_id());
		
		if("mpnews".equals(param.getMsgtype())) {
			if ("openId".equals(param.getSendMode())) {
				SendMsgMpnewsEntity mpnews = new SendMsgMpnewsEntity();
				mpnews.setTouser(param.getTouser());
				BaseMediaIdEntity media = new BaseMediaIdEntity();
				media.setMedia_id(param.getMedia_id());
				mpnews.setMpnews(media);
				mpnews.setMsgtype(param.getMsgtype());
				mpnews.setSend_ignore_reprint(param.getSend_ignore_reprint());
				
				sendMsgJsonStr = JSONObject.toJSONString(mpnews);
			} else if ("openIdpreview".equals(param.getSendMode())) {
				SendCustomMsgMpnewsEntity mpnews = new SendCustomMsgMpnewsEntity();
				mpnews.setTouser(param.getTouser()[0]);
				BaseMediaIdEntity media = new BaseMediaIdEntity();
				media.setMedia_id(param.getMedia_id());
				mpnews.setMpnews(media);
				mpnews.setMsgtype(param.getMsgtype());
				mpnews.setSend_ignore_reprint(param.getSend_ignore_reprint());
				
				sendMsgJsonStr = JSONObject.toJSONString(mpnews);
			} else if ("tag".equals(param.getSendMode())) {
				SendMsgMpnewsByTagEntity mpnews = new SendMsgMpnewsByTagEntity();
				mpnews.setFilter(filter);
				BaseMediaIdEntity media = new BaseMediaIdEntity();
				media.setMedia_id(param.getMedia_id());
				mpnews.setMpnews(media);
				mpnews.setMsgtype(param.getMsgtype());
				mpnews.setSend_ignore_reprint(param.getSend_ignore_reprint());
				
				sendMsgJsonStr = JSONObject.toJSONString(mpnews);
			}
			
		} else if("text".equals(param.getMsgtype())) {
			if ("openId".equals(param.getSendMode())) {
				SendMsgTextEntity text = new SendMsgTextEntity();
				text.setTouser(param.getTouser());
				BaseContentEntity content = new BaseContentEntity();
				content.setContent(param.getContent());
				text.setText(content);
				text.setMsgtype(param.getMsgtype());
			
				sendMsgJsonStr = JSONObject.toJSONString(text);
			} else if ("openIdpreview".equals(param.getSendMode())) {
				SendCustomMsgTextEntity text = new SendCustomMsgTextEntity();
				text.setTouser(param.getTouser()[0]);
				BaseContentEntity content = new BaseContentEntity();
				content.setContent(param.getContent());
				text.setText(content);
				text.setMsgtype(param.getMsgtype());
			
				sendMsgJsonStr = JSONObject.toJSONString(text);
			} else if ("tag".equals(param.getSendMode())) {
				
			}
		} else if("image".equals(param.getMsgtype())) {
			if ("openId".equals(param.getSendMode())) {
				SendMsgImageEntity image = new SendMsgImageEntity();
				image.setTouser(param.getTouser());
				BaseMediaIdEntity media = new BaseMediaIdEntity();
				media.setMedia_id(param.getMedia_id());
				image.setImage(media);
				image.setMsgtype(param.getMsgtype());
				
				sendMsgJsonStr = JSONObject.toJSONString(image);
			} else if ("openIdpreview".equals(param.getSendMode())) {
				SendCustomMsgImageEntity image = new SendCustomMsgImageEntity();
				image.setTouser(param.getTouser()[0]);
				BaseMediaIdEntity media = new BaseMediaIdEntity();
				media.setMedia_id(param.getMedia_id());
				image.setImage(media);
				image.setMsgtype(param.getMsgtype());
				
				sendMsgJsonStr = JSONObject.toJSONString(image);
			} else if ("tag".equals(param.getSendMode())) {
				
			}
		} 
		
		return sendMsgJsonStr;
	}
}
